<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>drag</title>
        <style>
        .draggable{
            width:100px;
            height:100px;
            background-color: lightcoral;
            position: absolute;
            cursor: move;
        }
    </style>
    </head>
    <body>
        <div class="draggable">

        </div>
        <button id="replay" style="position: fixed;right:0;">重放移动的过程</button>
        <script>
      let draggable = document.querySelector('.draggable');
      let replay = document.querySelector('#replay');
      //定义两个变量，用于存放鼠标与拖动元素的偏移量
      let offsetX=0,offsetY=0;
      //定义一个标志，用于标志当前是否正在拖动
      let dragging=false;
      //定义二个变量，记录此元素开始拖动时的起始位置
      let startLeft,startTop;
      //移动的历史
      let moveHistory = [];
      //为需要拖动的元素添加一个鼠标按下的监听器函数
      draggable.addEventListener('mousedown',(event)=>{
        //把dragging设置为true,表示开始拖动
        dragging=true;
        //计算鼠标点击位置 与拖动元素上边界和左边界的偏移量
        offsetX= event.offsetX;
        offsetY= event.offsetY;
        //记录初始位置 
        startLeft=draggable.offsetLeft;
        startTop =draggable.offsetTop;
      });
      document.addEventListener('mousemove',(event)=>{
        //如果正在拖动过程中，要实时重新计算元素的位置
        if(dragging){
            //在移动的过程中，获取每一步的位置 ，记录到数组
            let left = (event.clientX-offsetX);
            let top = (event.clientY-offsetY);
            //元素的left值等于当前光标距离左视口的距离，减去开始拖动的时候鼠标与拖动元素左边界的偏移量
            draggable.style.left = left+'px';
            //元素的left值等于当前光标距离上视口的距离，减去开始拖动的时候鼠标与拖动元素上边界的偏移量
            draggable.style.top = top +'px';
            moveHistory.push({left,top});
        }
      });
      draggable.addEventListener('mouseup',(event)=>{
        dragging=false;
      });
      replay.addEventListener('click',()=>{
        //先让元素回退到原始位置 
        draggable.style.left = startLeft+'px';
        draggable.style.top = startTop +'px';
        /*         
        //开启定时器，每隔16ms移动一下位置 
        let timer = setInterval(()=>{
            //取出数组最左则的元素
            let current = moveHistory.shift();
            //如果能取出，说明还有未回放的位置 
            if(current){
                //让元素移动到指定的位置 
                draggable.style.left = current.left+'px';
                draggable.style.top = current.top +'px';
            }else{//说明已经移动到位了，则清掉定时器
                clearInterval(timer);
            }
        },16); */

        function repaint(){
            //取出数组最左则的元素
            let current = moveHistory.shift();
            //如果能取出，说明还有未回放的位置 
            if(current){
                //让元素移动到指定的位置 
                draggable.style.left = current.left+'px';
                draggable.style.top = current.top +'px';
                requestAnimationFrame(repaint)
            }
        }
        requestAnimationFrame(repaint);
        //requestAnimationFrame
      });
   </script>
    </body>
</html>